{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## PyTorch图像分类器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torchvision\n",
    "import torchvision.transforms as transforms"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "torchvision数据集的输出是范围在[0,1]之间的PILImage，将他们转换成归一化范围为[-1,1]之间的张量Tensor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Using downloaded and verified file: ./data\\cifar-10-python.tar.gz\n",
      "Extracting ./data\\cifar-10-python.tar.gz to ./data\n",
      "Files already downloaded and verified\n"
     ]
    }
   ],
   "source": [
    "transform = transforms.Compose([transforms.ToTensor(),\n",
    "                                transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])\n",
    "trainset = torchvision.datasets.CIFAR10(root='./data', train=True,\n",
    "                                        download=True, transform=transform)\n",
    "trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,\n",
    "                                          shuffle=True, num_workers=2)\n",
    "testset = torchvision.datasets.CIFAR10(root='./data', train=False,\n",
    "                                       download=True, transform=transform)\n",
    "testloader = torch.utils.data.DataLoader(testset, batch_size=4,\n",
    "                                         shuffle=False, num_workers=2)\n",
    "classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " frog  ship  frog  bird\n"
     ]
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "# functions to show an image\n",
    "def imshow(img):\n",
    "    img = img / 2 + 0.5 # unnormalize\n",
    "    npimg = img.numpy()\n",
    "    plt.imshow(np.transpose(npimg, (1, 2, 0)))\n",
    "    plt.show()\n",
    "    \n",
    "# get some random training images\n",
    "dataiter = iter(trainloader)\n",
    "images, labels = dataiter.next()\n",
    "\n",
    "# show images\n",
    "imshow(torchvision.utils.make_grid(images))\n",
    "    \n",
    "# print labels\n",
    "print(' '.join('%5s' % classes[labels[j]] for j in range(4)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 定义3通道的神经网络"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Net(\n",
      "  (conv1): Conv2d(3, 6, kernel_size=(5, 5), stride=(1, 1))\n",
      "  (pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
      "  (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))\n",
      "  (fc1): Linear(in_features=400, out_features=120, bias=True)\n",
      "  (fc2): Linear(in_features=120, out_features=84, bias=True)\n",
      "  (fc3): Linear(in_features=84, out_features=10, bias=True)\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "class Net(nn.Module):\n",
    "    def __init__(self):\n",
    "        super(Net, self).__init__()\n",
    "        self.conv1 = nn.Conv2d(3, 6, 5)\n",
    "        self.pool = nn.MaxPool2d(2, 2)\n",
    "        self.conv2 = nn.Conv2d(6, 16, 5)\n",
    "        self.fc1 = nn.Linear(16 * 5 * 5, 120)\n",
    "        self.fc2 = nn.Linear(120, 84)\n",
    "        self.fc3 = nn.Linear(84, 10)\n",
    "            \n",
    "    def forward(self, x):\n",
    "        x = self.pool(F.relu(self.conv1(x)))\n",
    "        x = self.pool(F.relu(self.conv2(x)))\n",
    "        x = x.view(-1, 16 * 5 * 5)\n",
    "        x = F.relu(self.fc1(x))\n",
    "        x = F.relu(self.fc2(x))\n",
    "        x = self.fc3(x)\n",
    "        return x\n",
    "    \n",
    "net = Net()\n",
    "print(net)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Loss function: Cross-Entropy\n",
    "\n",
    "Optimization: 动量SGD"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch.optim as optim\n",
    "\n",
    "criterion = nn.CrossEntropyLoss()\n",
    "optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 训练网络"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1,  2000] loss: 2.221\n",
      "[1,  4000] loss: 1.910\n",
      "[1,  6000] loss: 1.731\n",
      "[1,  8000] loss: 1.638\n",
      "[1, 10000] loss: 1.571\n",
      "[1, 12000] loss: 1.512\n",
      "[2,  2000] loss: 1.418\n",
      "[2,  4000] loss: 1.395\n",
      "[2,  6000] loss: 1.372\n",
      "[2,  8000] loss: 1.330\n",
      "[2, 10000] loss: 1.324\n",
      "[2, 12000] loss: 1.267\n",
      "Finished Training\n"
     ]
    }
   ],
   "source": [
    "for epoch in range(2): # loop over the dataset multiple times\n",
    "    running_loss = 0.0\n",
    "    for i, data in enumerate(trainloader, 0):\n",
    "        # get the inputs\n",
    "        inputs, labels = data\n",
    "\n",
    "        # zero the parameter gradients\n",
    "        optimizer.zero_grad()\n",
    "\n",
    "        # forward + backward + optimize\n",
    "        outputs = net(inputs)\n",
    "        loss = criterion(outputs, labels)\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "\n",
    "        # print statistics\n",
    "        running_loss += loss.item()\n",
    "        if i % 2000 == 1999: # print every 2000 mini-batches\n",
    "            print('[%d, %5d] loss: %.3f' %\n",
    "                  (epoch + 1, i + 1, running_loss / 2000))\n",
    "            running_loss = 0.0\n",
    "        \n",
    "print('Finished Training')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "测试网络"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "GroundTruth:   deer  deer   dog  bird\n",
      "Predicted:   ship  ship   dog  bird\n"
     ]
    }
   ],
   "source": [
    "# get some random training images\n",
    "dataiter = iter(trainloader)\n",
    "images, labels = dataiter.next()\n",
    "imshow(torchvision.utils.make_grid(images))\n",
    "    \n",
    "# GroundTruth\n",
    "print('GroundTruth: ', ' '.join('%5s' % classes[labels[j]] \n",
    "                               for j in range(4)))\n",
    "# Predicted\n",
    "outputs = net(images)\n",
    "_, predicted = torch.max(outputs, 1)\n",
    "print('Predicted: ', ' '.join('%5s' % classes[predicted[j]] \n",
    "                              for j in range(4)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "测试在整个数据集上的表现"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy of the network on the 10000 test images: 53 %\n",
      "Accuracy of plane : 63 %\n",
      "Accuracy of   car : 78 %\n",
      "Accuracy of  bird : 39 %\n",
      "Accuracy of   cat : 37 %\n",
      "Accuracy of  deer : 31 %\n",
      "Accuracy of   dog : 44 %\n",
      "Accuracy of  frog : 61 %\n",
      "Accuracy of horse : 58 %\n",
      "Accuracy of  ship : 77 %\n",
      "Accuracy of truck : 44 %\n"
     ]
    }
   ],
   "source": [
    "correct = 0\n",
    "total = 0\n",
    "\n",
    "class_correct = list(0. for i in range(10))\n",
    "class_total = list(0. for i in range(10))\n",
    "\n",
    "with torch.no_grad():\n",
    "    for data in testloader:\n",
    "        images, labels = data\n",
    "        \n",
    "        outputs = net(images)\n",
    "        _, predicted = torch.max(outputs, 1)\n",
    "        \n",
    "        total += labels.size(0)\n",
    "        correct += (predicted == labels).sum().item()\n",
    "\n",
    "        c = (predicted == labels).squeeze()\n",
    "        for i in range(4):\n",
    "            label = labels[i]\n",
    "            class_correct[label] += c[i].item()\n",
    "            class_total[label] += 1\n",
    "\n",
    "print('Accuracy of the network on the 10000 test images: %d %%' % (100 * correct / total))\n",
    "for i in range(10):\n",
    "    print('Accuracy of %5s : %2d %%' % (classes[i], 100 * class_correct[i] / class_total[i]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 转到GPU运行"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "<torch.cuda.device object at 0x000001BA3162B240>\n",
      "1\n",
      "True\n",
      "cuda:0\n",
      "GeForce GTX 1050 Ti\n"
     ]
    }
   ],
   "source": [
    "print(torch.cuda.current_device())\n",
    "print(torch.cuda.device(0))\n",
    "print(torch.cuda.device_count())\n",
    "print(torch.cuda.is_available())\n",
    "\n",
    "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n",
    "print(device)\n",
    "\n",
    "print(torch.cuda.get_device_name(0))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "net = Net()\n",
    "net.to(device)\n",
    "criterion = nn.CrossEntropyLoss()\n",
    "optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1,  2000] loss: 2.249\n",
      "[1,  4000] loss: 1.939\n",
      "[1,  6000] loss: 1.717\n",
      "[1,  8000] loss: 1.620\n",
      "[1, 10000] loss: 1.556\n",
      "[1, 12000] loss: 1.490\n",
      "[2,  2000] loss: 1.437\n",
      "[2,  4000] loss: 1.388\n",
      "[2,  6000] loss: 1.369\n",
      "[2,  8000] loss: 1.324\n",
      "[2, 10000] loss: 1.338\n",
      "[2, 12000] loss: 1.288\n",
      "Finished Training\n"
     ]
    }
   ],
   "source": [
    "for epoch in range(2): # loop over the dataset multiple times\n",
    "    running_loss = 0.0\n",
    "    for i, data in enumerate(trainloader, 0):\n",
    "        # get the inputs\n",
    "        inputs, labels = data\n",
    "        inputs, labels = inputs.to(device), labels.to(device)\n",
    "\n",
    "        # zero the parameter gradients\n",
    "        optimizer.zero_grad()\n",
    "\n",
    "        # forward + backward + optimize\n",
    "        outputs = net(inputs)\n",
    "        loss = criterion(outputs, labels)\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "\n",
    "        # print statistics\n",
    "        running_loss += loss.item()\n",
    "        if i % 2000 == 1999: # print every 2000 mini-batches\n",
    "            print('[%d, %5d] loss: %.3f' %\n",
    "                  (epoch + 1, i + 1, running_loss / 2000))\n",
    "            running_loss = 0.0\n",
    "        \n",
    "print('Finished Training')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy of the network on the 10000 test images: 54 %\n",
      "Accuracy of plane : 49 %\n",
      "Accuracy of   car : 62 %\n",
      "Accuracy of  bird : 37 %\n",
      "Accuracy of   cat : 17 %\n",
      "Accuracy of  deer : 42 %\n",
      "Accuracy of   dog : 57 %\n",
      "Accuracy of  frog : 79 %\n",
      "Accuracy of horse : 63 %\n",
      "Accuracy of  ship : 62 %\n",
      "Accuracy of truck : 73 %\n"
     ]
    }
   ],
   "source": [
    "correct = 0\n",
    "total = 0\n",
    "\n",
    "class_correct = list(0. for i in range(10))\n",
    "class_total = list(0. for i in range(10))\n",
    "\n",
    "with torch.no_grad():\n",
    "    for data in testloader:\n",
    "        images, labels = data\n",
    "        images, labels = images.to(device), labels.to(device)\n",
    "        \n",
    "        outputs = net(images)\n",
    "        _, predicted = torch.max(outputs, 1)\n",
    "        \n",
    "        total += labels.size(0)\n",
    "        correct += (predicted == labels).sum().item()\n",
    "\n",
    "        c = (predicted == labels).squeeze()\n",
    "        for i in range(4):\n",
    "            label = labels[i]\n",
    "            class_correct[label] += c[i].item()\n",
    "            class_total[label] += 1\n",
    "\n",
    "print('Accuracy of the network on the 10000 test images: %d %%' % (100 * correct / total))\n",
    "for i in range(10):\n",
    "    print('Accuracy of %5s : %2d %%' % (classes[i], 100 * class_correct[i] / class_total[i]))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
